import config from "@/static/ts/config";

// 定义接口响应类型
interface ApiResponse<T> {
  code: number; // 状态码
  msg: string; // 消息
  data: T; // 响应数据
}

// 用于标记是否已经跳转到登录页
let isRedirecting = false;

// 通用请求函数
const request = <T = any>(
  url: string,
  method: "GET" | "POST" | "PUT" | "DELETE",
  data?: any
): Promise<T> => {
  var userInfo = uni.getStorageSync("userInfo");
  if (data?.loading == 1) {
    uni.showLoading();
    delete data.loading;
  }
  return new Promise((resolve, reject) => {
    uni.request({
      url: `${config.baseUrl}${url}`,
      method,
      data,
      header: {
        token: userInfo.token || "",
      },
      success: (response) => {
        const { statusCode, data } = response;

        if (statusCode === 200) {
          // 确保响应结构符合定义
          if (isApiResponse(data)) {
            const { code, msg, data: responseData } = data;

            switch (code) {
              case 0: // 请求成功
                resolve(responseData);
                break;
              case -1: // 函数错误，提示 msg
                uni.showToast({ title: msg, icon: "none" });
                reject(new Error(msg));
                break;
              case -500: // token 无效
                handleInvalidToken();
                reject(new Error("登录状态已过期"));
                break;
              case -100: // 被挤下线
                handleInvalidToken("账号在其他地方登录");
                reject(new Error("账号在其他地方登录"));
                break;
              default: // 其他错误
                uni.showToast({ title: msg || "未知错误", icon: "none" });
                reject(new Error(msg || "未知错误"));
                break;
            }
          } else {
            uni.showToast({ title: "响应格式错误", icon: "none" });
            reject(new Error("响应格式错误"));
          }
        } else {
          uni.showToast({ title: `HTTP 错误: ${statusCode}`, icon: "none" });
          reject(new Error(`HTTP 错误: ${statusCode}`));
        }
      },
      fail: (error) => {
        uni.showToast({ title: "网络请求失败，请检查网络连接", icon: "none" });
        reject(error);
      },
      complete: () => {
        uni.hideLoading();
      },
    });
  });
};

// 处理 token 无效和账号被挤下线逻辑
const handleInvalidToken = (message: string = "登录状态已过期，请重新登录") => {
  if (!isRedirecting) {
    isRedirecting = true; // 设置跳转状态
    uni.showToast({
      title: message,
      icon: "none",
      duration: 2000, // 确保提示用户后再跳转
    });
    setTimeout(() => {
      uni.reLaunch({
        url: "/pages/notLoggedIn/login",
        complete: () => {
          isRedirecting = false; // 跳转完成后重置状态
        },
      });
    }, 2000); // 延迟跳转，确保用户能看到提示
  }
};

// 类型守卫函数
function isApiResponse(data: any): data is ApiResponse<any> {
  return (
    typeof data === "object" && data !== null && "code" in data && "msg" in data
  );
}

// GET 请求封装
export const get = <T = any>(url: string, params?: Record<string, any>) => {
  const queryString = params
    ? "?" +
      Object.entries(params)
        .map(
          ([key, value]) =>
            `${encodeURIComponent(key)}=${encodeURIComponent(value)}`
        )
        .join("&")
    : "";
  return request<T>(url + queryString, "GET");
};

// POST 请求封装
export const post = <T = any>(url: string, data?: any) => {
  return request<T>(url, "POST", data);
};

// PUT 请求封装
export const put = <T = any>(url: string, data?: any) => {
  return request<T>(url, "PUT", data);
};

// DELETE 请求封装
export const del = <T = any>(url: string, data?: any) => {
  return request<T>(url, "DELETE", data);
};

export default request;
